package model.playable.unit;
import model.command.*;
import model.playable.*;
import java.util.*;
import model.visibility.*;
import model.mapping.*;
import model.map.*;

public class Vehicle extends BasicUnit implements Unloadable
{
	private int capacity;
	private Unit[] passengers;
	
	public Vehicle(PlayableUser player, List<String> walkableTerrains)
	{
		setWalkableTerrains(walkableTerrains);
		setPlayer(player);
		setIdNumber(-1);
		setUpkeep(1);
		setInfluenceRadius(0);
		setVisibilityRadius(1);
		setCommandQueue(new LinkedList<Command>());
		setCommandsPossibleList(createCommandPossibleList());
		setCurrentPossibleCommandPosition(0);
		setIsInStandBy(false);
		setIsPoweredDown(false);
		setArmyId(-1);
		setRallyPointId(-1);
		setMovementSpeed(1);
		setIsBattleGroup(false);
		setIsReinforcement(false);
		setArmor(10);
		setHealth(40);
		setMaxHealth(40);
		setOffensiveDamage(20);
		setDefensiveDamage(20);
		setIsSoldier(false);
		setCapacity(5);
		setPassengers(new Unit[5]);
	}
	
	public LinkedList<Command> createCommandPossibleList()
	{
		LinkedList<Command> possibleCommands = new LinkedList<Command>();
		possibleCommands.add(new PowerDown(this));
		possibleCommands.add(new PowerUp(this));
		possibleCommands.add(new Decommission(this));
		possibleCommands.add(new Standby(this));
		possibleCommands.add(new Attack(this));
		possibleCommands.add(new Defend(this));
		possibleCommands.add(new Move(this));
		return possibleCommands;
	}
	
	public void incrementHealth(int increment)
	{
		super.incrementHealth(increment);
		if(health <= 0)
			getPlayer().removeVehicle(this);
	}
	
	public int getCapacity()
	{
		return capacity;
	}
	
	public void setCapacity(int capacity)
	{
		this.capacity = capacity;
	}
	
	public Unit[] getPassengers()
	{
		return passengers;
	}
	
	public void setPassengers(Unit[] passengers)
	{
		this.passengers = passengers;
	}
	
	public void loadPassenger(Unit unit)
	{
		for(int i = 0; i < capacity; i++)
		{
			if(passengers[i] == null)
			{
				passengers[i] = unit;
			}
		}
	}
	
	public void unloadPassengers()
	{
		passengers = new Unit[capacity];
	}
	
	public void decommission()
	{
		getPlayer().removeVehicle(this);
	}
	
	public void accept(PlayableVisitor pv)
	{
		pv.visitVehicle(this);
	}
	
	public GameTile getLocation()
	{
		return PlayableMapping.getPlayableMapping().getLocationOfVehicle(this);
	}
	
	public void move(Direction direction)
	{
		PlayableMapping map = PlayableMapping.getPlayableMapping();
		GameTile tile = map.getLocationOfVehicle(this);
		GameTile neighbor = tile.getNeighborAt(direction);
		if ((neighbor != null) && !map.isObstructedForPlayer(neighbor, getPlayer()) && isWalkable(neighbor.getTerrainType()))
		{
			map.removeVehicle(this);
			map.addVehicle(neighbor, this);
			System.out.println("This unit executed move " + direction.toString() );
		}
		else
		{
			System.out.println("This unit cannot move " + direction.toString());
		}
	} 

	public void unload()
	{
		PlayableMapping map = PlayableMapping.getPlayableMapping();
		GameTile tile = map.getLocationOfUnit(this);
		for(int i = 0; i < capacity; i++)
		{
			if(passengers[i] == null)
			{
				map.addUnit(tile, passengers[i]);
			}
		}
	}
	
	public String toString()
	{
		return "Vehicle";
	}
}